home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / aplictns / matlab / src.6 < prev    next >
Internet Message Format  |  1988-11-02  |  54KB

  1. Path: xanth!nic.MR.NET!hal!cwjcc!mailrus!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i046:  matlab - matrix laboratory, Part06/11
  5. Message-ID: <10021@swan.ulowell.edu>
  6. Date: 2 Nov 88 21:45:11 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1220
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: strovink%galaxy-43@afit-ab.arpa (Mark A. Strovink)
  12. Posting-number: Volume 2, Issue 46
  13. Archive-name: applications/matlab/src.6
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    src-6
  23. # This archive created: Wed Nov  2 16:20:42 1988
  24. cat << \SHAR_EOF > src-6
  25.       SMALL = 1.D0/2.D0**48               
  26. C                      
  27. C     DETERMINE WHAT IS TO BE COMPUTED.   
  28. C                      
  29.       WANTU = .FALSE.                     
  30.       WANTV = .FALSE.                     
  31.       JOBU = MOD(JOB,100)/10              
  32.       NCU = N          
  33.       IF (JOBU .GT. 1) NCU = MIN0(N,P)    
  34.       IF (JOBU .NE. 0) WANTU = .TRUE.     
  35.       IF (MOD(JOB,10) .NE. 0) WANTV = .TRUE.                 
  36. C                      
  37. C     REDUCE X TO BIDIAGONAL FORM, STORING THE DIAGONAL ELEMENTS                
  38. C     IN S AND THE SUPER-DIAGONAL ELEMENTS IN E.             
  39. C                      
  40.       INFO = 0         
  41.       NCT = MIN0(N-1,P)                   
  42.       NRT = MAX0(0,MIN0(P-2,N))           
  43.       LU = MAX0(NCT,NRT)                  
  44.       IF (LU .LT. 1) GO TO 190            
  45.       DO 180 L = 1, LU                    
  46.          LP1 = L + 1   
  47.          IF (L .GT. NCT) GO TO 30         
  48. C                      
  49. C           COMPUTE THE TRANSFORMATION FOR THE L-TH COLUMN AND                  
  50. C           PLACE THE L-TH DIAGONAL IN S(L).                 
  51. C                      
  52.             SR(L) = WNRM2(N-L+1,XR(L,L),XI(L,L),1)           
  53.             SI(L) = 0.0D0                 
  54.             IF (CABS1(SR(L),SI(L)) .EQ. 0.0D0) GO TO 20      
  55.                IF (CABS1(XR(L,L),XI(L,L)) .EQ. 0.0D0) GO TO 10                  
  56.                   CALL WSIGN(SR(L),SI(L),XR(L,L),XI(L,L),SR(L),SI(L))           
  57.    10          CONTINUE                   
  58.                CALL WDIV(1.0D0,0.0D0,SR(L),SI(L),TR,TI)      
  59.                CALL WSCAL(N-L+1,TR,TI,XR(L,L),XI(L,L),1)     
  60.                XR(L,L) = FLOP(1.0D0 + XR(L,L))               
  61.    20       CONTINUE   
  62.             SR(L) = -SR(L)                
  63.             SI(L) = -SI(L)                
  64.    30    CONTINUE      
  65.          IF (P .LT. LP1) GO TO 60         
  66.          DO 50 J = LP1, P                 
  67.             IF (L .GT. NCT) GO TO 40      
  68.             IF (CABS1(SR(L),SI(L)) .EQ. 0.0D0) GO TO 40      
  69. C                      
  70. C              APPLY THE TRANSFORMATION.  
  71. C                      
  72.                TR = -WDOTCR(N-L+1,XR(L,L),XI(L,L),1,XR(L,J),XI(L,J),1)          
  73.                TI = -WDOTCI(N-L+1,XR(L,L),XI(L,L),1,XR(L,J),XI(L,J),1)          
  74.                CALL WDIV(TR,TI,XR(L,L),XI(L,L),TR,TI)        
  75.                CALL WAXPY(N-L+1,TR,TI,XR(L,L),XI(L,L),1,XR(L,J),                
  76.      * XI(L,J),1)      
  77.    40       CONTINUE   
  78. C                      
  79. C           PLACE THE L-TH ROW OF X INTO  E FOR THE          
  80. C           SUBSEQUENT CALCULATION OF THE ROW TRANSFORMATION.                   
  81. C                      
  82.             ER(J) = XR(L,J)               
  83.             EI(J) = -XI(L,J)              
  84.    50    CONTINUE      
  85.    60    CONTINUE      
  86.          IF (.NOT.WANTU .OR. L .GT. NCT) GO TO 80            
  87. C                      
  88. C           PLACE THE TRANSFORMATION IN U FOR SUBSEQUENT BACK                   
  89. C           MULTIPLICATION.               
  90. C                      
  91.             DO 70 I = L, N                
  92.                UR(I,L) = XR(I,L)          
  93.                UI(I,L) = XI(I,L)          
  94.    70       CONTINUE   
  95.    80    CONTINUE      
  96.          IF (L .GT. NRT) GO TO 170        
  97. C                      
  98. C           COMPUTE THE L-TH ROW TRANSFORMATION AND PLACE THE                   
  99. C           L-TH SUPER-DIAGONAL IN E(L).  
  100. C                      
  101.             ER(L) = WNRM2(P-L,ER(LP1),EI(LP1),1)             
  102.             EI(L) = 0.0D0                 
  103.             IF (CABS1(ER(L),EI(L)) .EQ. 0.0D0) GO TO 100     
  104.                IF (CABS1(ER(LP1),EI(LP1)) .EQ. 0.0D0) GO TO 90                  
  105.                   CALL WSIGN(ER(L),EI(L),ER(LP1),EI(LP1),ER(L),EI(L))           
  106.    90          CONTINUE                   
  107.                CALL WDIV(1.0D0,0.0D0,ER(L),EI(L),TR,TI)      
  108.                CALL WSCAL(P-L,TR,TI,ER(LP1),EI(LP1),1)       
  109.                ER(LP1) = FLOP(1.0D0 + ER(LP1))               
  110.   100       CONTINUE   
  111.             ER(L) = -ER(L)                
  112.             EI(L) = +EI(L)                
  113.             IF (LP1 .GT. N .OR. CABS1(ER(L),EI(L)) .EQ. 0.0D0)                  
  114.      *         GO TO 140                  
  115. C                      
  116. C              APPLY THE TRANSFORMATION.  
  117. C                      
  118.                DO 110 I = LP1, N          
  119.                   WORKR(I) = 0.0D0        
  120.                   WORKI(I) = 0.0D0        
  121.   110          CONTINUE                   
  122.                DO 120 J = LP1, P          
  123.                   CALL WAXPY(N-L,ER(J),EI(J),XR(LP1,J),XI(LP1,J),1,             
  124.      *    WORKR(LP1),WORKI(LP1),1)        
  125.   120          CONTINUE                   
  126.                DO 130 J = LP1, P          
  127.                   CALL WDIV(-ER(J),-EI(J),ER(LP1),EI(LP1),TR,TI)                
  128.                   CALL WAXPY(N-L,TR,-TI,WORKR(LP1),WORKI(LP1),1,                
  129.      *    XR(LP1,J),XI(LP1,J),1)          
  130.   130          CONTINUE                   
  131.   140       CONTINUE   
  132.             IF (.NOT.WANTV) GO TO 160     
  133. C                      
  134. C              PLACE THE TRANSFORMATION IN V FOR SUBSEQUENT  
  135. C              BACK MULTIPLICATION.       
  136. C                      
  137.                DO 150 I = LP1, P          
  138.                   VR(I,L) = ER(I)         
  139.                   VI(I,L) = EI(I)         
  140.   150          CONTINUE                   
  141.   160       CONTINUE   
  142.   170    CONTINUE      
  143.   180 CONTINUE         
  144.   190 CONTINUE         
  145. C                      
  146. C     SET UP THE FINAL BIDIAGONAL MATRIX OR ORDER M.         
  147. C                      
  148.       M = MIN0(P,N+1)                     
  149.       NCTP1 = NCT + 1                     
  150.       NRTP1 = NRT + 1                     
  151.       IF (NCT .GE. P) GO TO 200           
  152.          SR(NCTP1) = XR(NCTP1,NCTP1)      
  153.          SI(NCTP1) = XI(NCTP1,NCTP1)      
  154.   200 CONTINUE         
  155.       IF (N .GE. M) GO TO 210             
  156.          SR(M) = 0.0D0                    
  157.          SI(M) = 0.0D0                    
  158.   210 CONTINUE         
  159.       IF (NRTP1 .GE. M) GO TO 220         
  160.          ER(NRTP1) = XR(NRTP1,M)          
  161.          EI(NRTP1) = XI(NRTP1,M)          
  162.   220 CONTINUE         
  163.       ER(M) = 0.0D0    
  164.       EI(M) = 0.0D0    
  165. C                      
  166. C     IF REQUIRED, GENERATE U.            
  167. C                      
  168.       IF (.NOT.WANTU) GO TO 350           
  169.          IF (NCU .LT. NCTP1) GO TO 250    
  170.          DO 240 J = NCTP1, NCU            
  171.             DO 230 I = 1, N               
  172.                UR(I,J) = 0.0D0            
  173.                UI(I,J) = 0.0D0            
  174.   230       CONTINUE   
  175.             UR(J,J) = 1.0D0               
  176.             UI(J,J) = 0.0D0               
  177.   240    CONTINUE      
  178.   250    CONTINUE      
  179.          IF (NCT .LT. 1) GO TO 340        
  180.          DO 330 LL = 1, NCT               
  181.             L = NCT - LL + 1              
  182.             IF (CABS1(SR(L),SI(L)) .EQ. 0.0D0) GO TO 300     
  183.                LP1 = L + 1                
  184.                IF (NCU .LT. LP1) GO TO 270                   
  185.                DO 260 J = LP1, NCU        
  186.                   TR = -WDOTCR(N-L+1,UR(L,L),UI(L,L),1,UR(L,J),                 
  187.      *      UI(L,J),1)                    
  188.                   TI = -WDOTCI(N-L+1,UR(L,L),UI(L,L),1,UR(L,J),                 
  189.      *      UI(L,J),1)                    
  190.                   CALL WDIV(TR,TI,UR(L,L),UI(L,L),TR,TI)     
  191.                   CALL WAXPY(N-L+1,TR,TI,UR(L,L),UI(L,L),1,UR(L,J),             
  192.      *    UI(L,J),1)   
  193.   260          CONTINUE                   
  194.   270          CONTINUE                   
  195.                CALL WRSCAL(N-L+1,-1.0D0,UR(L,L),UI(L,L),1)   
  196.                UR(L,L) = FLOP(1.0D0 + UR(L,L))               
  197.                LM1 = L - 1                
  198.                IF (LM1 .LT. 1) GO TO 290  
  199.                DO 280 I = 1, LM1          
  200.                   UR(I,L) = 0.0D0         
  201.                   UI(I,L) = 0.0D0         
  202.   280          CONTINUE                   
  203.   290          CONTINUE                   
  204.             GO TO 320                     
  205.   300       CONTINUE   
  206.                DO 310 I = 1, N            
  207.                   UR(I,L) = 0.0D0         
  208.                   UI(I,L) = 0.0D0         
  209.   310          CONTINUE                   
  210.                UR(L,L) = 1.0D0            
  211.                UI(L,L) = 0.0D0            
  212.   320       CONTINUE   
  213.   330    CONTINUE      
  214.   340    CONTINUE      
  215.   350 CONTINUE         
  216. C                      
  217. C     IF IT IS REQUIRED, GENERATE V.      
  218. C                      
  219.       IF (.NOT.WANTV) GO TO 400           
  220.          DO 390 LL = 1, P                 
  221.             L = P - LL + 1                
  222.             LP1 = L + 1                   
  223.             IF (L .GT. NRT) GO TO 370     
  224.             IF (CABS1(ER(L),EI(L)) .EQ. 0.0D0) GO TO 370     
  225.                DO 360 J = LP1, P          
  226.                   TR = -WDOTCR(P-L,VR(LP1,L),VI(LP1,L),1,VR(LP1,J),             
  227.      *      VI(LP1,J),1)                  
  228.                   TI = -WDOTCI(P-L,VR(LP1,L),VI(LP1,L),1,VR(LP1,J),             
  229.      *      VI(LP1,J),1)                  
  230.                   CALL WDIV(TR,TI,VR(LP1,L),VI(LP1,L),TR,TI) 
  231.                   CALL WAXPY(P-L,TR,TI,VR(LP1,L),VI(LP1,L),1,VR(LP1,J),         
  232.      *    VI(LP1,J),1)                    
  233.   360          CONTINUE                   
  234.   370       CONTINUE   
  235.             DO 380 I = 1, P               
  236.                VR(I,L) = 0.0D0            
  237.                VI(I,L) = 0.0D0            
  238.   380       CONTINUE   
  239.             VR(L,L) = 1.0D0               
  240.             VI(L,L) = 0.0D0               
  241.   390    CONTINUE      
  242.   400 CONTINUE         
  243. C                      
  244. C     TRANSFORM S AND E SO THAT THEY ARE REAL.               
  245. C                      
  246.       DO 420 I = 1, M                     
  247.             TR = PYTHAG(SR(I),SI(I))      
  248.             IF (TR .EQ. 0.0D0) GO TO 405  
  249.             RR = SR(I)/TR                 
  250.             RI = SI(I)/TR                 
  251.             SR(I) = TR                    
  252.             SI(I) = 0.0D0                 
  253.             IF (I .LT. M) CALL WDIV(ER(I),EI(I),RR,RI,ER(I),EI(I))              
  254.             IF (WANTU) CALL WSCAL(N,RR,RI,UR(1,I),UI(1,I),1) 
  255.   405    CONTINUE      
  256. C     ...EXIT          
  257.          IF (I .EQ. M) GO TO 430          
  258.             TR = PYTHAG(ER(I),EI(I))      
  259.             IF (TR .EQ. 0.0D0) GO TO 410  
  260.             CALL WDIV(TR,0.0D0,ER(I),EI(I),RR,RI)            
  261.             ER(I) = TR                    
  262.             EI(I) = 0.0D0                 
  263.             CALL WMUL(SR(I+1),SI(I+1),RR,RI,SR(I+1),SI(I+1)) 
  264.             IF (WANTV) CALL WSCAL(P,RR,RI,VR(1,I+1),VI(1,I+1),1)                
  265.   410    CONTINUE      
  266.   420 CONTINUE         
  267.   430 CONTINUE         
  268. C                      
  269. C     MAIN ITERATION LOOP FOR THE SINGULAR VALUES.           
  270. C                      
  271.       MM = M           
  272.       ITER = 0         
  273.   440 CONTINUE         
  274. C                      
  275. C        QUIT IF ALL THE SINGULAR VALUES HAVE BEEN FOUND.    
  276. C                      
  277. C     ...EXIT          
  278.          IF (M .EQ. 0) GO TO 700          
  279. C                      
  280. C        IF TOO MANY ITERATIONS HAVE BEEN PERFORMED, SET     
  281. C        FLAG AND RETURN.                 
  282. C                      
  283.          IF (ITER .LT. MAXIT) GO TO 450   
  284.             INFO = M   
  285. C     ......EXIT       
  286.             GO TO 700                     
  287.   450    CONTINUE      
  288. C                      
  289. C        THIS SECTION OF THE PROGRAM INSPECTS FOR            
  290. C        NEGLIGIBLE ELEMENTS IN THE S AND E ARRAYS.  ON      
  291. C        COMPLETION THE VARIABLE KASE IS SET AS FOLLOWS.     
  292. C                      
  293. C           KASE = 1     IF SR(M) AND ER(L-1) ARE NEGLIGIBLE AND L.LT.M         
  294. C           KASE = 2     IF SR(L) IS NEGLIGIBLE AND L.LT.M   
  295. C           KASE = 3     IF ER(L-1) IS NEGLIGIBLE, L.LT.M, AND                  
  296. C     SR(L), ..., SR(M) ARE NOT NEGLIGIBLE (QR STEP).        
  297. C           KASE = 4     IF ER(M-1) IS NEGLIGIBLE (CONVERGENCE).                
  298. C                      
  299.          DO 470 LL = 1, M                 
  300.             L = M - LL                    
  301. C        ...EXIT       
  302.             IF (L .EQ. 0) GO TO 480       
  303.             TEST = FLOP(DABS(SR(L)) + DABS(SR(L+1)))         
  304.             ZTEST = FLOP(TEST + DABS(ER(L))/2.0D0)           
  305.             IF (SMALL*ZTEST .NE. SMALL*TEST) GO TO 460       
  306.                ER(L) = 0.0D0              
  307. C        ......EXIT    
  308.                GO TO 480                  
  309.   460       CONTINUE   
  310.   470    CONTINUE      
  311.   480    CONTINUE      
  312.          IF (L .NE. M - 1) GO TO 490      
  313.             KASE = 4   
  314.          GO TO 560     
  315.   490    CONTINUE      
  316.             LP1 = L + 1                   
  317.             MP1 = M + 1                   
  318.             DO 510 LLS = LP1, MP1         
  319.                LS = M - LLS + LP1         
  320. C           ...EXIT    
  321.                IF (LS .EQ. L) GO TO 520   
  322.                TEST = 0.0D0               
  323.                IF (LS .NE. M) TEST = FLOP(TEST + DABS(ER(LS)))                  
  324.                IF (LS .NE. L + 1) TEST = FLOP(TEST + DABS(ER(LS-1)))            
  325.                ZTEST = FLOP(TEST + DABS(SR(LS))/2.0D0)       
  326.                IF (SMALL*ZTEST .NE. SMALL*TEST) GO TO 500    
  327.                   SR(LS) = 0.0D0          
  328. C           ......EXIT                    
  329.                   GO TO 520               
  330.   500          CONTINUE                   
  331.   510       CONTINUE   
  332.   520       CONTINUE   
  333.             IF (LS .NE. L) GO TO 530      
  334.                KASE = 3                   
  335.             GO TO 550                     
  336.   530       CONTINUE   
  337.             IF (LS .NE. M) GO TO 540      
  338.                KASE = 1                   
  339.             GO TO 550                     
  340.   540       CONTINUE   
  341.                KASE = 2                   
  342.                L = LS                     
  343.   550       CONTINUE   
  344.   560    CONTINUE      
  345.          L = L + 1     
  346. C                      
  347. C        PERFORM THE TASK INDICATED BY KASE.                 
  348. C                      
  349.          GO TO (570, 600, 620, 650), KASE                    
  350. C                      
  351. C        DEFLATE NEGLIGIBLE SR(M).        
  352. C                      
  353.   570    CONTINUE      
  354.             MM1 = M - 1                   
  355.             F = ER(M-1)                   
  356.             ER(M-1) = 0.0D0               
  357.             DO 590 KK = L, MM1            
  358.                K = MM1 - KK + L           
  359.                T1 = SR(K)                 
  360.                CALL RROTG(T1,F,CS,SN)     
  361.                SR(K) = T1                 
  362.                IF (K .EQ. L) GO TO 580    
  363.                   F = FLOP(-SN*ER(K-1))   
  364.                   ER(K-1) = FLOP(CS*ER(K-1))                 
  365.   580          CONTINUE                   
  366.                IF (WANTV) CALL RROT(P,VR(1,K),1,VR(1,M),1,CS,SN)                
  367.                IF (WANTV) CALL RROT(P,VI(1,K),1,VI(1,M),1,CS,SN)                
  368.   590       CONTINUE   
  369.          GO TO 690     
  370. C                      
  371. C        SPLIT AT NEGLIGIBLE SR(L).       
  372. C                      
  373.   600    CONTINUE      
  374.             F = ER(L-1)                   
  375.             ER(L-1) = 0.0D0               
  376.             DO 610 K = L, M               
  377.                T1 = SR(K)                 
  378.                CALL RROTG(T1,F,CS,SN)     
  379.                SR(K) = T1                 
  380.                F = FLOP(-SN*ER(K))        
  381.                ER(K) = FLOP(CS*ER(K))     
  382.                IF (WANTU) CALL RROT(N,UR(1,K),1,UR(1,L-1),1,CS,SN)              
  383.                IF (WANTU) CALL RROT(N,UI(1,K),1,UI(1,L-1),1,CS,SN)              
  384.   610       CONTINUE   
  385.          GO TO 690     
  386. C                      
  387. C        PERFORM ONE QR STEP.             
  388. C                      
  389.   620    CONTINUE      
  390. C                      
  391. C           CALCULATE THE SHIFT.          
  392. C                      
  393.             SCALE = DMAX1(DABS(SR(M)),DABS(SR(M-1)),DABS(ER(M-1)),              
  394.      * DABS(SR(L)),DABS(ER(L)))           
  395.             SM = SR(M)/SCALE              
  396.             SMM1 = SR(M-1)/SCALE          
  397.             EMM1 = ER(M-1)/SCALE          
  398.             SL = SR(L)/SCALE              
  399.             EL = ER(L)/SCALE              
  400.             B = FLOP(((SMM1 + SM)*(SMM1 - SM) + EMM1**2)/2.0D0)                 
  401.             C = FLOP((SM*EMM1)**2)        
  402.             SHIFT = 0.0D0                 
  403.             IF (B .EQ. 0.0D0 .AND. C .EQ. 0.0D0) GO TO 630   
  404.                SHIFT = FLOP(DSQRT(B**2+C))                   
  405.                IF (B .LT. 0.0D0) SHIFT = -SHIFT              
  406.                SHIFT = FLOP(C/(B + SHIFT))                   
  407.   630       CONTINUE   
  408.             F = FLOP((SL + SM)*(SL - SM) - SHIFT)            
  409.             G = FLOP(SL*EL)               
  410. C                      
  411. C           CHASE ZEROS.                  
  412. C                      
  413.             MM1 = M - 1                   
  414.             DO 640 K = L, MM1             
  415.                CALL RROTG(F,G,CS,SN)      
  416.                IF (K .NE. L) ER(K-1) = F  
  417.                F = FLOP(CS*SR(K) + SN*ER(K))                 
  418.                ER(K) = FLOP(CS*ER(K) - SN*SR(K))             
  419.                G = FLOP(SN*SR(K+1))       
  420.                SR(K+1) = FLOP(CS*SR(K+1))                    
  421.                IF (WANTV) CALL RROT(P,VR(1,K),1,VR(1,K+1),1,CS,SN)              
  422.                IF (WANTV) CALL RROT(P,VI(1,K),1,VI(1,K+1),1,CS,SN)              
  423.                CALL RROTG(F,G,CS,SN)      
  424.                SR(K) = F                  
  425.                F = FLOP(CS*ER(K) + SN*SR(K+1))               
  426.                SR(K+1) = FLOP(-SN*ER(K) + CS*SR(K+1))        
  427.                G = FLOP(SN*ER(K+1))       
  428.                ER(K+1) = FLOP(CS*ER(K+1))                    
  429.                IF (WANTU .AND. K .LT. N)  
  430.      *            CALL RROT(N,UR(1,K),1,UR(1,K+1),1,CS,SN)   
  431.                IF (WANTU .AND. K .LT. N)  
  432.      *            CALL RROT(N,UI(1,K),1,UI(1,K+1),1,CS,SN)   
  433.   640       CONTINUE   
  434.             ER(M-1) = F                   
  435.             ITER = ITER + 1               
  436.          GO TO 690     
  437. C                      
  438. C        CONVERGENCE   
  439. C                      
  440.   650    CONTINUE      
  441. C                      
  442. C           MAKE THE SINGULAR VALUE  POSITIVE                
  443. C                      
  444.             IF (SR(L) .GE. 0.0D0) GO TO 660                  
  445.                SR(L) = -SR(L)             
  446.              IF (WANTV) CALL WRSCAL(P,-1.0D0,VR(1,L),VI(1,L),1)                 
  447.   660       CONTINUE   
  448. C                      
  449. C           ORDER THE SINGULAR VALUE.     
  450. C                      
  451.   670       IF (L .EQ. MM) GO TO 680      
  452. C           ...EXIT    
  453.                IF (SR(L) .GE. SR(L+1)) GO TO 680             
  454.                TR = SR(L)                 
  455.                SR(L) = SR(L+1)            
  456.                SR(L+1) = TR               
  457.                IF (WANTV .AND. L .LT. P)  
  458.      *            CALL WSWAP(P,VR(1,L),VI(1,L),1,VR(1,L+1),VI(1,L+1),1)         
  459.                IF (WANTU .AND. L .LT. N)  
  460.      *            CALL WSWAP(N,UR(1,L),UI(1,L),1,UR(1,L+1),UI(1,L+1),1)         
  461.                L = L + 1                  
  462.             GO TO 670                     
  463.   680       CONTINUE   
  464.             ITER = 0   
  465.             M = M - 1                     
  466.   690    CONTINUE      
  467.       GO TO 440        
  468.   700 CONTINUE         
  469.       RETURN           
  470.       END              
  471.       SUBROUTINE WQRDC(XR,XI,LDX,N,P,QRAUXR,QRAUXI,JPVT,WORKR,WORKI,            
  472.      *                 JOB)               
  473.       INTEGER LDX,N,P,JOB                 
  474.       INTEGER JPVT(1)                     
  475.       DOUBLE PRECISION XR(LDX,1),XI(LDX,1),QRAUXR(1),QRAUXI(1),                 
  476.      *                 WORKR(1),WORKI(1)  
  477. C                      
  478. C     WQRDC USES HOUSEHOLDER TRANSFORMATIONS TO COMPUTE THE QR                  
  479. C     FACTORIZATION OF AN N BY P MATRIX X.  COLUMN PIVOTING  
  480. C     BASED ON THE 2-NORMS OF THE REDUCED COLUMNS MAY BE     
  481. C     PERFORMED AT THE USERS OPTION.      
  482. C                      
  483. C     ON ENTRY         
  484. C                      
  485. C        X       DOUBLE-COMPLEX(LDX,P), WHERE LDX .GE. N.    
  486. C                X CONTAINS THE MATRIX WHOSE DECOMPOSITION IS TO BE             
  487. C                COMPUTED.                
  488. C                      
  489. C        LDX     INTEGER.                 
  490. C                LDX IS THE LEADING DIMENSION OF THE ARRAY X.                   
  491. C                      
  492. C        N       INTEGER.                 
  493. C                N IS THE NUMBER OF ROWS OF THE MATRIX X.    
  494. C                      
  495. C        P       INTEGER.                 
  496. C                P IS THE NUMBER OF COLUMNS OF THE MATRIX X. 
  497. C                      
  498. C        JPVT    INTEGER(P).              
  499. C                JPVT CONTAINS INTEGERS THAT CONTROL THE SELECTION              
  500. C                OF THE PIVOT COLUMNS.  THE K-TH COLUMN X(K) OF X               
  501. C                IS PLACED IN ONE OF THREE CLASSES ACCORDING TO THE             
  502. C                VALUE OF JPVT(K).        
  503. C                      
  504. C                   IF JPVT(K) .GT. 0, THEN X(K) IS AN INITIAL                  
  505. C                   COLUMN.               
  506. C                      
  507. C                   IF JPVT(K) .EQ. 0, THEN X(K) IS A FREE COLUMN.              
  508. C                      
  509. C                   IF JPVT(K) .LT. 0, THEN X(K) IS A FINAL COLUMN.             
  510. C                      
  511. C                BEFORE THE DECOMPOSITION IS COMPUTED, INITIAL COLUMNS          
  512. C                ARE MOVED TO THE BEGINNING OF THE ARRAY X AND FINAL            
  513. C                COLUMNS TO THE END.  BOTH INITIAL AND FINAL COLUMNS            
  514. C                ARE FROZEN IN PLACE DURING THE COMPUTATION AND ONLY            
  515. C                FREE COLUMNS ARE MOVED.  AT THE K-TH STAGE OF THE              
  516. C                REDUCTION, IF X(K) IS OCCUPIED BY A FREE COLUMN                
  517. C                IT IS INTERCHANGED WITH THE FREE COLUMN OF LARGEST             
  518. C                REDUCED NORM.  JPVT IS NOT REFERENCED IF    
  519. C                JOB .EQ. 0.              
  520. C                      
  521. C        WORK    DOUBLE-COMPLEX(P).       
  522. C                WORK IS A WORK ARRAY.  WORK IS NOT REFERENCED IF               
  523. C                JOB .EQ. 0.              
  524. C                      
  525. C        JOB     INTEGER.                 
  526. C                JOB IS AN INTEGER THAT INITIATES COLUMN PIVOTING.              
  527. C                IF JOB .EQ. 0, NO PIVOTING IS DONE.         
  528. C                IF JOB .NE. 0, PIVOTING IS DONE.            
  529. C                      
  530. C     ON RETURN        
  531. C                      
  532. C        X       X CONTAINS IN ITS UPPER TRIANGLE THE UPPER  
  533. C                TRIANGULAR MATRIX R OF THE QR FACTORIZATION.                   
  534. C                BELOW ITS DIAGONAL X CONTAINS INFORMATION FROM                 
  535. C                WHICH THE UNITARY PART OF THE DECOMPOSITION 
  536. C                CAN BE RECOVERED.  NOTE THAT IF PIVOTING HAS                   
  537. C                BEEN REQUESTED, THE DECOMPOSITION IS NOT THAT                  
  538. C                OF THE ORIGINAL MATRIX X BUT THAT OF X      
  539. C                WITH ITS COLUMNS PERMUTED AS DESCRIBED BY JPVT.                
  540. C                      
  541. C        QRAUX   DOUBLE-COMPLEX(P).       
  542. C                QRAUX CONTAINS FURTHER INFORMATION REQUIRED TO RECOVER         
  543. C                THE UNITARY PART OF THE DECOMPOSITION.      
  544. C                      
  545. C        JPVT    JPVT(K) CONTAINS THE INDEX OF THE COLUMN OF THE                
  546. C                ORIGINAL MATRIX THAT HAS BEEN INTERCHANGED INTO                
  547. C                THE K-TH COLUMN, IF PIVOTING WAS REQUESTED. 
  548. C                      
  549. C     LINPACK. THIS VERSION DATED 07/03/79 .                 
  550. C     G.W. STEWART, UNIVERSITY OF MARYLAND, ARGONNE NATIONAL LAB.               
  551. C                      
  552. C     WQRDC USES THE FOLLOWING FUNCTIONS AND SUBPROGRAMS.    
  553. C                      
  554. C     BLAS WAXPY,PYTHAG,WDOTCR,WDOTCI,WSCAL,WSWAP,WNRM2      
  555. C     FORTRAN DABS,DIMAG,DMAX1,MIN0       
  556. C                      
  557. C     INTERNAL VARIABLES                  
  558. C                      
  559.       INTEGER J,JP,L,LP1,LUP,MAXJ,PL,PU   
  560.       DOUBLE PRECISION MAXNRM,WNRM2,TT    
  561.       DOUBLE PRECISION PYTHAG,WDOTCR,WDOTCI,NRMXLR,NRMXLI,TR,TI,FLOP            
  562.       LOGICAL NEGJ,SWAPJ                  
  563. C                      
  564.       DOUBLE PRECISION ZDUMR,ZDUMI        
  565.       DOUBLE PRECISION CABS1              
  566.       CABS1(ZDUMR,ZDUMI) = DABS(ZDUMR) + DABS(ZDUMI)         
  567. C                      
  568.       PL = 1           
  569.       PU = 0           
  570.       IF (JOB .EQ. 0) GO TO 60            
  571. C                      
  572. C        PIVOTING HAS BEEN REQUESTED.  REARRANGE THE COLUMNS 
  573. C        ACCORDING TO JPVT.               
  574. C                      
  575.          DO 20 J = 1, P                   
  576.             SWAPJ = JPVT(J) .GT. 0        
  577.             NEGJ = JPVT(J) .LT. 0         
  578.             JPVT(J) = J                   
  579.             IF (NEGJ) JPVT(J) = -J        
  580.             IF (.NOT.SWAPJ) GO TO 10      
  581.                IF (J .NE. PL)             
  582.      *            CALL WSWAP(N,XR(1,PL),XI(1,PL),1,XR(1,J),XI(1,J),1)           
  583.                JPVT(J) = JPVT(PL)         
  584.                JPVT(PL) = J               
  585.                PL = PL + 1                
  586.    10       CONTINUE   
  587.    20    CONTINUE      
  588.          PU = P        
  589.          DO 50 JJ = 1, P                  
  590.             J = P - JJ + 1                
  591.             IF (JPVT(J) .GE. 0) GO TO 40  
  592.                JPVT(J) = -JPVT(J)         
  593.                IF (J .EQ. PU) GO TO 30    
  594.                   CALL WSWAP(N,XR(1,PU),XI(1,PU),1,XR(1,J),XI(1,J),1)           
  595.                   JP = JPVT(PU)           
  596.                   JPVT(PU) = JPVT(J)      
  597.                   JPVT(J) = JP            
  598.    30          CONTINUE            
  599.        
  600.                PU = PU - 1                
  601.    40       CONTINUE   
  602.    50    CONTINUE      
  603.    60 CONTINUE         
  604. C                      
  605. C     COMPUTE THE NORMS OF THE FREE COLUMNS.                 
  606. C                      
  607.       IF (PU .LT. PL) GO TO 80            
  608.       DO 70 J = PL, PU                    
  609.          QRAUXR(J) = WNRM2(N,XR(1,J),XI(1,J),1)              
  610.          QRAUXI(J) = 0.0D0                
  611.          WORKR(J) = QRAUXR(J)             
  612.          WORKI(J) = QRAUXI(J)             
  613.    70 CONTINUE         
  614.    80 CONTINUE         
  615. C                      
  616. C     PERFORM THE HOUSEHOLDER REDUCTION OF X.                
  617. C                      
  618.       LUP = MIN0(N,P)                     
  619.       DO 210 L = 1, LUP                   
  620.          IF (L .LT. PL .OR. L .GE. PU) GO TO 120             
  621. C                      
  622. C           LOCATE THE COLUMN OF LARGEST NORM AND BRING IT   
  623. C           INTO THE PIVOT POSITION.      
  624. C                      
  625.             MAXNRM = 0.0D0                
  626.             MAXJ = L   
  627.             DO 100 J = L, PU              
  628.                IF (QRAUXR(J) .LE. MAXNRM) GO TO 90           
  629.                   MAXNRM = QRAUXR(J)      
  630.                   MAXJ = J                
  631.    90          CONTINUE                   
  632.   100       CONTINUE   
  633.             IF (MAXJ .EQ. L) GO TO 110    
  634.                CALL WSWAP(N,XR(1,L),XI(1,L),1,XR(1,MAXJ),XI(1,MAXJ),1)          
  635.                QRAUXR(MAXJ) = QRAUXR(L)   
  636.                QRAUXI(MAXJ) = QRAUXI(L)   
  637.                WORKR(MAXJ) = WORKR(L)     
  638.                WORKI(MAXJ) = WORKI(L)     
  639.                JP = JPVT(MAXJ)            
  640.                JPVT(MAXJ) = JPVT(L)       
  641.                JPVT(L) = JP               
  642.   110       CONTINUE   
  643.   120    CONTINUE      
  644.          QRAUXR(L) = 0.0D0                
  645.          QRAUXI(L) = 0.0D0                
  646.          IF (L .EQ. N) GO TO 200          
  647. C                      
  648. C           COMPUTE THE HOUSEHOLDER TRANSFORMATION FOR COLUMN L.                
  649. C                      
  650.             NRMXLR = WNRM2(N-L+1,XR(L,L),XI(L,L),1)          
  651.             NRMXLI = 0.0D0                
  652.             IF (CABS1(NRMXLR,NRMXLI) .EQ. 0.0D0) GO TO 190   
  653.                IF (CABS1(XR(L,L),XI(L,L)) .EQ. 0.0D0) GO TO 130                 
  654.                  CALL WSIGN(NRMXLR,NRMXLI,XR(L,L),XI(L,L),NRMXLR,NRMXLI)        
  655.   130          CONTINUE                   
  656.                CALL WDIV(1.0D0,0.0D0,NRMXLR,NRMXLI,TR,TI)    
  657.                CALL WSCAL(N-L+1,TR,TI,XR(L,L),XI(L,L),1)     
  658.                XR(L,L) = FLOP(1.0D0 + XR(L,L))               
  659. C                      
  660. C              APPLY THE TRANSFORMATION TO THE REMAINING COLUMNS,               
  661. C              UPDATING THE NORMS.        
  662. C                      
  663.                LP1 = L + 1                
  664.                IF (P .LT. LP1) GO TO 180  
  665.                DO 170 J = LP1, P          
  666.                   TR = -WDOTCR(N-L+1,XR(L,L),XI(L,L),1,XR(L,J),                 
  667.      *      XI(L,J),1)                    
  668.                   TI = -WDOTCI(N-L+1,XR(L,L),XI(L,L),1,XR(L,J),                 
  669.      *      XI(L,J),1)                    
  670.                   CALL WDIV(TR,TI,XR(L,L),XI(L,L),TR,TI)     
  671.                   CALL WAXPY(N-L+1,TR,TI,XR(L,L),XI(L,L),1,XR(L,J),             
  672.      *    XI(L,J),1)   
  673.                   IF (J .LT. PL .OR. J .GT. PU) GO TO 160    
  674.                   IF (CABS1(QRAUXR(J),QRAUXI(J)) .EQ. 0.0D0) 
  675.      *               GO TO 160            
  676.                     TT = 1.0D0 - (PYTHAG(XR(L,J),XI(L,J))/QRAUXR(J))**2        
  677.                     TT = DMAX1(TT,0.0D0)                    
  678.                     TR = FLOP(TT)        
  679.                     TT = FLOP(1.0D0+0.05D0*TT*(QRAUXR(J)/WORKR(J))**2)         
  680.                     IF (TT .EQ. 1.0D0) GO TO 140            
  681.                      QRAUXR(J) = QRAUXR(J)*DSQRT(TR)      
  682.                      QRAUXI(J) = QRAUXI(J)*DSQRT(TR)      
  683.                      GO TO 150            
  684.   140                CONTINUE             
  685.       QRAUXR(J) = WNRM2(N-L,XR(L+1,J),XI(L+1,J),1)            
  686.       QRAUXI(J) = 0.0D0                    
  687.       WORKR(J) = QRAUXR(J)                 
  688.       WORKI(J) = QRAUXI(J)                 
  689.   150                CONTINUE             
  690.   160             CONTINUE                
  691.   170          CONTINUE                   
  692.   180          CONTINUE                   
  693. C                      
  694. C              SAVE THE TRANSFORMATION.   
  695. C                      
  696.                QRAUXR(L) = XR(L,L)        
  697.                QRAUXI(L) = XI(L,L)        
  698.                XR(L,L) = -NRMXLR          
  699.                XI(L,L) = -NRMXLI          
  700.   190       CONTINUE   
  701.   200    CONTINUE      
  702.   210 CONTINUE         
  703.       RETURN           
  704.       END              
  705.       SUBROUTINE WQRSL(XR,XI,LDX,N,K,QRAUXR,QRAUXI,YR,YI,QYR,QYI,QTYR,          
  706.      *                 QTYI,BR,BI,RSDR,RSDI,XBR,XBI,JOB,INFO)                   
  707.       INTEGER LDX,N,K,JOB,INFO            
  708.       DOUBLE PRECISION XR(LDX,1),XI(LDX,1),QRAUXR(1),QRAUXI(1),YR(1),           
  709.      *                 YI(1),QYR(1),QYI(1),QTYR(1),QTYI(1),BR(1),BI(1),         
  710.      *                 RSDR(1),RSDI(1),XBR(1),XBI(1)         
  711. C                      
  712. C     WQRSL APPLIES THE OUTPUT OF WQRDC TO COMPUTE COORDINATE                   
  713. C     TRANSFORMATIONS, PROJECTIONS, AND LEAST SQUARES SOLUTIONS.                
  714. C     FOR K .LE. MIN(N,P), LET XK BE THE MATRIX              
  715. C                      
  716. C            XK = (X(JPVT(1)),X(JPVT(2)), ... ,X(JPVT(K)))   
  717. C                      
  718. C     FORMED FROM COLUMNNS JPVT(1), ... ,JPVT(K) OF THE ORIGINAL                
  719. C     N X P MATRIX X THAT WAS INPUT TO WQRDC (IF NO PIVOTING WAS                
  720. C     DONE, XK CONSISTS OF THE FIRST K COLUMNS OF X IN THEIR 
  721. C     ORIGINAL ORDER).  WQRDC PRODUCES A FACTORED UNITARY MATRIX Q              
  722. C     AND AN UPPER TRIANGULAR MATRIX R SUCH THAT             
  723. C                      
  724. C              XK = Q * (R)               
  725. C    (0)               
  726. C                      
  727. C     THIS INFORMATION IS CONTAINED IN CODED FORM IN THE ARRAYS                 
  728. C     X AND QRAUX.     
  729. C                      
  730. C     ON ENTRY         
  731. C                      
  732. C        X      DOUBLE-COMPLEX(LDX,P).    
  733. C               X CONTAINS THE OUTPUT OF WQRDC.              
  734. C                      
  735. C        LDX    INTEGER.                  
  736. C               LDX IS THE LEADING DIMENSION OF THE ARRAY X. 
  737. C                      
  738. C        N      INTEGER.                  
  739. C               N IS THE NUMBER OF ROWS OF THE MATRIX XK.  IT MUST              
  740. C               HAVE THE SAME VALUE AS N IN WQRDC.           
  741. C                      
  742. C        K      INTEGER.                  
  743. C               K IS THE NUMBER OF COLUMNS OF THE MATRIX XK.  K                 
  744. C               MUST NNOT BE GREATER THAN MIN(N,P), WHERE P IS THE              
  745. C               SAME AS IN THE CALLING SEQUENCE TO WQRDC.    
  746. C                      
  747. C        QRAUX  DOUBLE-COMPLEX(P).        
  748. C               QRAUX CONTAINS THE AUXILIARY OUTPUT FROM WQRDC.                 
  749. C                      
  750. C        Y      DOUBLE-COMPLEX(N)         
  751. C               Y CONTAINS AN N-VECTOR THAT IS TO BE MANIPULATED                
  752. C               BY WQRSL.                 
  753. C                      
  754. C        JOB    INTEGER.                  
  755. C               JOB SPECIFIES WHAT IS TO BE COMPUTED.  JOB HAS                  
  756. C               THE DECIMAL EXPANSION ABCDE, WITH THE FOLLOWING                 
  757. C               MEANING.                  
  758. C                      
  759. C IF A.NE.0, COMPUTE QY.                  
  760. C IF B,C,D, OR E .NE. 0, COMPUTE QTY.     
  761. C IF C.NE.0, COMPUTE B.                   
  762. C IF D.NE.0, COMPUTE RSD.                 
  763. C IF E.NE.0, COMPUTE XB.                  
  764. C                      
  765. C               NOTE THAT A REQUEST TO COMPUTE B, RSD, OR XB 
  766. C               AUTOMATICALLY TRIGGERS THE COMPUTATION OF QTY, FOR              
  767. C               WHICH AN ARRAY MUST BE PROVIDED IN THE CALLING                  
  768. C               SEQUENCE.                 
  769. C                      
  770. C     ON RETURN        
  771. C                      
  772. C        QY     DOUBLE-COMPLEX(N).        
  773. C               QY CONNTAINS Q*Y, IF ITS COMPUTATION HAS BEEN                   
  774. C               REQUESTED.                
  775. C                      
  776. C        QTY    DOUBLE-COMPLEX(N).        
  777. C               QTY CONTAINS CTRANS(Q)*Y, IF ITS COMPUTATION HAS                
  778. C               BEEN REQUESTED.  HERE CTRANS(Q) IS THE CONJUGATE                
  779. C               TRANSPOSE OF THE MATRIX Q.                   
  780. C                      
  781. C        B      DOUBLE-COMPLEX(K)         
  782. C               B CONTAINS THE SOLUTION OF THE LEAST SQUARES PROBLEM            
  783. C                      
  784. C MINIMIZE NORM2(Y - XK*B),               
  785. C                      
  786. C               IF ITS COMPUTATION HAS BEEN REQUESTED.  (NOTE THAT              
  787. C               IF PIVOTING WAS REQUESTED IN WQRDC, THE J-TH 
  788. C               COMPONENT OF B WILL BE ASSOCIATED WITH COLUMN JPVT(J)           
  789. C               OF THE ORIGINAL MATRIX X THAT WAS INPUT INTO WQRDC.)            
  790. C                      
  791. C        RSD    DOUBLE-COMPLEX(N).        
  792. C               RSD CONTAINS THE LEAST SQUARES RESIDUAL Y - XK*B,               
  793. C               IF ITS COMPUTATION HAS BEEN REQUESTED.  RSD IS                  
  794. C               ALSO THE ORTHOGONAL PROJECTION OF Y ONTO THE 
  795. C               ORTHOGONAL COMPLEMENT OF THE COLUMN SPACE OF XK.                
  796. C                      
  797. C        XB     DOUBLE-COMPLEX(N).        
  798. C               XB CONTAINS THE LEAST SQUARES APPROXIMATION XK*B,               
  799. C               IF ITS COMPUTATION HAS BEEN REQUESTED.  XB IS ALSO              
  800. C               THE ORTHOGONAL PROJECTION OF Y ONTO THE COLUMN SPACE            
  801. C               OF X.                     
  802. C                      
  803. C        INFO   INTEGER.                  
  804. C               INFO IS ZERO UNLESS THE COMPUTATION OF B HAS 
  805. C               BEEN REQUESTED AND R IS EXACTLY SINGULAR.  IN                   
  806. C               THIS CASE, INFO IS THE INDEX OF THE FIRST ZERO                  
  807. C               DIAGONAL ELEMENT OF R AND B IS LEFT UNALTERED.                  
  808. C                      
  809. C     THE PARAMETERS QY, QTY, B, RSD, AND XB ARE NOT REFERENCED                 
  810. C     IF THEIR COMPUTATION IS NOT REQUESTED AND IN THIS CASE 
  811. C     CAN BE REPLACED BY DUMMY VARIABLES IN THE CALLING PROGRAM.                
  812. C     TO SAVE STORAGE, THE USER MAY IN SOME CASES USE THE SAME                  
  813. C     ARRAY FOR DIFFERENT PARAMETERS IN THE CALLING SEQUENCE.  A                
  814. C     FREQUENTLY OCCURING EXAMPLE IS WHEN ONE WISHES TO COMPUTE                 
  815. C     ANY OF B, RSD, OR XB AND DOES NOT NEED Y OR QTY.  IN THIS                 
  816. C     CASE ONE MAY IDENTIFY Y, QTY, AND ONE OF B, RSD, OR XB, WHILE             
  817. C     PROVIDING SEPARATE ARRAYS FOR ANYTHING ELSE THAT IS TO BE                 
  818. C     COMPUTED.  THUS THE CALLING SEQUENCE                   
  819. C                      
  820. C          CALL WQRSL(X,LDX,N,K,QRAUX,Y,DUM,Y,B,Y,DUM,110,INFO)                 
  821. C                      
  822. C     WILL RESULT IN THE COMPUTATION OF B AND RSD, WITH RSD  
  823. C     OVERWRITING Y.  MORE GENERALLY, EACH ITEM IN THE FOLLOWING                
  824. C     LIST CONTAINS GROUPS OF PERMISSIBLE IDENTIFICATIONS FOR                   
  825. C     A SINGLE CALLINNG SEQUENCE.         
  826. C                      
  827. C          1. (Y,QTY,B) (RSD) (XB) (QY)   
  828. C                      
  829. C          2. (Y,QTY,RSD) (B) (XB) (QY)   
  830. C                      
  831. C          3. (Y,QTY,XB) (B) (RSD) (QY)   
  832. C                      
  833. C          4. (Y,QY) (QTY,B) (RSD) (XB)   
  834. C                      
  835. C          5. (Y,QY) (QTY,RSD) (B) (XB)   
  836. C                      
  837. C          6. (Y,QY) (QTY,XB) (B) (RSD)   
  838. C                      
  839. C     IN ANY GROUP THE VALUE RETURNED IN THE ARRAY ALLOCATED TO                 
  840. C     THE GROUP CORRESPONDS TO THE LAST MEMBER OF THE GROUP. 
  841. C                      
  842. C     LINPACK. THIS VERSION DATED 07/03/79 .                 
  843. C     G.W. STEWART, UNIVERSITY OF MARYLAND, ARGONNE NATIONAL LAB.               
  844. C                      
  845. C     WQRSL USES THE FOLLOWING FUNCTIONS AND SUBPROGRAMS.    
  846. C                      
  847. C     BLAS WAXPY,WCOPY,WDOTCR,WDOTCI      
  848. C     FORTRAN DABS,DIMAG,MIN0,MOD         
  849. C                      
  850. C     INTERNAL VARIABLES                  
  851. C                      
  852.       INTEGER I,J,JJ,JU,KP1               
  853.       DOUBLE PRECISION WDOTCR,WDOTCI,TR,TI,TEMPR,TEMPI       
  854.       LOGICAL CB,CQY,CQTY,CR,CXB          
  855. C                      
  856.       DOUBLE PRECISION ZDUMR,ZDUMI        
  857.       DOUBLE PRECISION CABS1              
  858.       CABS1(ZDUMR,ZDUMI) = DABS(ZDUMR) + DABS(ZDUMI)         
  859. C                      
  860. C     SET INFO FLAG.   
  861. C                      
  862.       INFO = 0         
  863. C                      
  864. C     DETERMINE WHAT IS TO BE COMPUTED.   
  865. C                      
  866.       CQY = JOB/10000 .NE. 0              
  867.       CQTY = MOD(JOB,10000) .NE. 0        
  868.       CB = MOD(JOB,1000)/100 .NE. 0       
  869.       CR = MOD(JOB,100)/10 .NE. 0         
  870.       CXB = MOD(JOB,10) .NE. 0            
  871.       JU = MIN0(K,N-1)                    
  872. C                      
  873. C     SPECIAL ACTION WHEN N=1.            
  874. C                      
  875.       IF (JU .NE. 0) GO TO 80             
  876.          IF (.NOT.CQY) GO TO 10           
  877.             QYR(1) = YR(1)                
  878.             QYI(1) = YI(1)                
  879.    10    CONTINUE      
  880.          IF (.NOT.CQTY) GO TO 20          
  881.             QTYR(1) = YR(1)               
  882.             QTYI(1) = YI(1)               
  883.    20    CONTINUE      
  884.          IF (.NOT.CXB) GO TO 30           
  885.             XBR(1) = YR(1)                
  886.             XBI(1) = YI(1)                
  887.    30    CONTINUE      
  888.          IF (.NOT.CB) GO TO 60            
  889.             IF (CABS1(XR(1,1),XI(1,1)) .NE. 0.0D0) GO TO 40  
  890.                INFO = 1                   
  891.             GO TO 50   
  892.    40       CONTINUE   
  893.                CALL WDIV(YR(1),YI(1),XR(1,1),XI(1,1),BR(1),BI(1))               
  894.    50       CONTINUE   
  895.    60    CONTINUE      
  896.          IF (.NOT.CR) GO TO 70            
  897.             RSDR(1) = 0.0D0               
  898.             RSDI(1) = 0.0D0               
  899.    70    CONTINUE      
  900.       GO TO 290        
  901.    80 CONTINUE         
  902. C                      
  903. C        SET UP TO COMPUTE QY OR QTY.     
  904. C                      
  905.          IF (CQY) CALL WCOPY(N,YR,YI,1,QYR,QYI,1)            
  906.          IF (CQTY) CALL WCOPY(N,YR,YI,1,QTYR,QTYI,1)         
  907.          IF (.NOT.CQY) GO TO 110          
  908. C                      
  909. C           COMPUTE QY.                   
  910. C                      
  911.             DO 100 JJ = 1, JU             
  912.                J = JU - JJ + 1            
  913.                IF (CABS1(QRAUXR(J),QRAUXI(J)) .EQ. 0.0D0)    
  914.      *            GO TO 90                
  915.                   TEMPR = XR(J,J)         
  916.                   TEMPI = XI(J,J)         
  917.                   XR(J,J) = QRAUXR(J)     
  918.                   XI(J,J) = QRAUXI(J)     
  919.                   TR = -WDOTCR(N-J+1,XR(J,J),XI(J,J),1,QYR(J),QYI(J),1)         
  920.                   TI = -WDOTCI(N-J+1,XR(J,J),XI(J,J),1,QYR(J),QYI(J),1)         
  921.                   CALL WDIV(TR,TI,XR(J,J),XI(J,J),TR,TI)     
  922.                   CALL WAXPY(N-J+1,TR,TI,XR(J,J),XI(J,J),1,QYR(J),              
  923.      *    QYI(J),1)    
  924.                   XR(J,J) = TEMPR         
  925.                   XI(J,J) = TEMPI         
  926.    90          CONTINUE                   
  927.   100       CONTINUE   
  928.   110    CONTINUE      
  929.          IF (.NOT.CQTY) GO TO 140         
  930. C                      
  931. C           COMPUTE CTRANS(Q)*Y.          
  932. C                      
  933.             DO 130 J = 1, JU              
  934.                IF (CABS1(QRAUXR(J),QRAUXI(J)) .EQ. 0.0D0)    
  935.      *            GO TO 120               
  936.                   TEMPR = XR(J,J)         
  937.                   TEMPI = XI(J,J)         
  938.                   XR(J,J) = QRAUXR(J)     
  939.                   XI(J,J) = QRAUXI(J)     
  940.                   TR = -WDOTCR(N-J+1,XR(J,J),XI(J,J),1,QTYR(J),                 
  941.      *      QTYI(J),1)                    
  942.                   TI = -WDOTCI(N-J+1,XR(J,J),XI(J,J),1,QTYR(J),                 
  943.      *      QTYI(J),1)                    
  944.                   CALL WDIV(TR,TI,XR(J,J),XI(J,J),TR,TI)     
  945.                   CALL WAXPY(N-J+1,TR,TI,XR(J,J),XI(J,J),1,QTYR(J),             
  946.      *    QTYI(J),1)   
  947.                   XR(J,J) = TEMPR         
  948.                   XI(J,J) = TEMPI         
  949.   120          CONTINUE                   
  950.   130       CONTINUE   
  951.   140    CONTINUE      
  952. C                      
  953. C        SET UP TO COMPUTE B, RSD, OR XB.                    
  954. C                      
  955.          IF (CB) CALL WCOPY(K,QTYR,QTYI,1,BR,BI,1)           
  956.          KP1 = K + 1   
  957.          IF (CXB) CALL WCOPY(K,QTYR,QTYI,1,XBR,XBI,1)        
  958.          IF (CR .AND. K .LT. N)           
  959.      *      CALL WCOPY(N-K,QTYR(KP1),QTYI(KP1),1,RSDR(KP1),RSDI(KP1),1)         
  960.          IF (.NOT.CXB .OR. KP1 .GT. N) GO TO 160             
  961.             DO 150 I = KP1, N             
  962.                XBR(I) = 0.0D0             
  963.                XBI(I) = 0.0D0             
  964.   150       CONTINUE   
  965.   160    CONTINUE      
  966.          IF (.NOT.CR) GO TO 180           
  967.             DO 170 I = 1, K               
  968.                RSDR(I) = 0.0D0            
  969.                RSDI(I) = 0.0D0            
  970.   170       CONTINUE   
  971.   180    CONTINUE      
  972.          IF (.NOT.CB) GO TO 230           
  973. C                      
  974. C           COMPUTE B.                    
  975. C                      
  976.             DO 210 JJ = 1, K              
  977.                J = K - JJ + 1             
  978.                IF (CABS1(XR(J,J),XI(J,J)) .NE. 0.0D0) GO TO 190                 
  979.                   INFO = J                
  980. C                 ......EXIT              
  981. C           ......EXIT                    
  982.                   GO TO 220               
  983.   190          CONTINUE                   
  984.                CALL WDIV(BR(J),BI(J),XR(J,J),XI(J,J),BR(J),BI(J))               
  985.                IF (J .EQ. 1) GO TO 200    
  986.                   TR = -BR(J)             
  987.                   TI = -BI(J)             
  988.                   CALL WAXPY(J-1,TR,TI,XR(1,J),XI(1,J),1,BR,BI,1)               
  989.   200          CONTINUE                   
  990.   210       CONTINUE   
  991.   220       CONTINUE   
  992.   230    CONTINUE      
  993.          IF (.NOT.CR .AND. .NOT.CXB) GO TO 280               
  994. C                      
  995. C           COMPUTE RSD OR XB AS REQUIRED.                   
  996. C                      
  997.             DO 270 JJ = 1, JU             
  998.                J = JU - JJ + 1            
  999.                IF (CABS1(QRAUXR(J),QRAUXI(J)) .EQ. 0.0D0)    
  1000.      *            GO TO 260               
  1001.                   TEMPR = XR(J,J)         
  1002.                   TEMPI = XI(J,J)         
  1003.                   XR(J,J) = QRAUXR(J)     
  1004.                   XI(J,J) = QRAUXI(J)     
  1005.                   IF (.NOT.CR) GO TO 240  
  1006.                   TR = -WDOTCR(N-J+1,XR(J,J),XI(J,J),1,RSDR(J),              
  1007.      *         RSDI(J),1)                 
  1008.                   TI = -WDOTCI(N-J+1,XR(J,J),XI(J,J),1,RSDR(J),              
  1009.      *         RSDI(J),1)                 
  1010.                   CALL WDIV(TR,TI,XR(J,J),XI(J,J),TR,TI)  
  1011.                   CALL WAXPY(N-J+1,TR,TI,XR(J,J),XI(J,J),1,RSDR(J),          
  1012.      *       RSDI(J),1)                   
  1013.   240             CONTINUE                
  1014.                   IF (.NOT.CXB) GO TO 250                    
  1015.                    TR = -WDOTCR(N-J+1,XR(J,J),XI(J,J),1,XBR(J),               
  1016.      *         XBI(J),1)                  
  1017.                    TI = -WDOTCI(N-J+1,XR(J,J),XI(J,J),1,XBR(J),               
  1018.      *         XBI(J),1)                  
  1019.                    CALL WDIV(TR,TI,XR(J,J),XI(J,J),TR,TI)  
  1020.                    CALL WAXPY(N-J+1,TR,TI,XR(J,J),XI(J,J),1,XBR(J),           
  1021.      *       XBI(J),1)                    
  1022.   250             CONTINUE                
  1023.                   XR(J,J) = TEMPR         
  1024.                   XI(J,J) = TEMPI         
  1025.   260          CONTINUE                   
  1026.   270       CONTINUE   
  1027.   280    CONTINUE      
  1028.   290 CONTINUE         
  1029.       RETURN           
  1030.       END              
  1031.       SUBROUTINE MAGIC(A,LDA,N)           
  1032. C                      
  1033. C     ALGORITHMS FOR MAGIC SQUARES TAKEN FROM                
  1034. C        MATHEMATICAL RECREATIONS AND ESSAYS, 12TH ED.,      
  1035. C        BY W. W. ROUSE BALL AND H. S. M. COXETER            
  1036. C                      
  1037.       DOUBLE PRECISION A(LDA,N),T         
  1038. C                      
  1039.       IF (MOD(N,4) .EQ. 0) GO TO 100      
  1040.       IF (MOD(N,2) .EQ. 0) M = N/2        
  1041.       IF (MOD(N,2) .NE. 0) M = N          
  1042. C                      
  1043. C     ODD ORDER OR UPPER CORNER OF EVEN ORDER                
  1044. C                      
  1045.       DO 20 J = 1,M    
  1046.          DO 10 I = 1,M                    
  1047.             A(I,J) = 0                    
  1048.    10    CONTINUE      
  1049.    20 CONTINUE         
  1050.       I = 1            
  1051.       J = (M+1)/2      
  1052.       MM = M*M         
  1053.       DO 40 K = 1, MM                     
  1054.          A(I,J) = K    
  1055.          I1 = I-1      
  1056.          J1 = J+1      
  1057.          IF(I1.LT.1) I1 = M               
  1058.          IF(J1.GT.M) J1 = 1               
  1059.          IF(IDINT(A(I1,J1)).EQ.0) GO TO 30                   
  1060.             I1 = I+1   
  1061.             J1 = J     
  1062.    30    I = I1        
  1063.          J = J1        
  1064.    40 CONTINUE         
  1065.       IF (MOD(N,2) .NE. 0) RETURN         
  1066. C                      
  1067. C     REST OF EVEN ORDER                  
  1068. C                      
  1069.       T = M*M          
  1070.       DO 60 I = 1, M   
  1071.          DO 50 J = 1, M                   
  1072.             IM = I+M   
  1073.             JM = J+M   
  1074.             A(I,JM) = A(I,J) + 2*T        
  1075.             A(IM,J) = A(I,J) + 3*T        
  1076.             A(IM,JM) = A(I,J) + T         
  1077.    50    CONTINUE      
  1078.    60 CONTINUE         
  1079.       M1 = (M-1)/2     
  1080.       IF (M1.EQ.0) RETURN                 
  1081.       DO 70 J = 1, M1                     
  1082.          CALL RSWAP(M,A(1,J),1,A(M+1,J),1)                   
  1083.    70 CONTINUE         
  1084.       M1 = (M+1)/2     
  1085.       M2 = M1 + M      
  1086.       CALL RSWAP(1,A(M1,1),1,A(M2,1),1)   
  1087.       CALL RSWAP(1,A(M1,M1),1,A(M2,M1),1)                    
  1088.       M1 = N+1-(M-3)/2                    
  1089.       IF(M1.GT.N) RETURN                  
  1090.       DO 80 J = M1, N                     
  1091.          CALL RSWAP(M,A(1,J),1,A(M+1,J),1)                   
  1092.    80 CONTINUE         
  1093.       RETURN           
  1094. C                      
  1095. C     DOUBLE EVEN ORDER                   
  1096. C                      
  1097.   100 K = 1            
  1098.       DO 120 I = 1, N                     
  1099.          DO 110 J = 1, N                  
  1100.             A(I,J) = K                    
  1101.             IF (MOD(I,4)/2 .EQ. MOD(J,4)/2) A(I,J) = N*N+1 - K                  
  1102.             K = K+1    
  1103.   110    CONTINUE      
  1104.   120 CONTINUE         
  1105.       RETURN           
  1106.       END              
  1107.       SUBROUTINE BASE(X,B,EPS,S,N)        
  1108.       DOUBLE PRECISION X,B,EPS,S(1),T     
  1109. C                      
  1110. C     STORE BASE B REPRESENTATION OF X IN S(1:N)             
  1111. C                      
  1112.       INTEGER PLUS,MINUS,DOT,ZERO,COMMA   
  1113.       DATA PLUS/41/,MINUS/42/,DOT/47/,ZERO/0/,COMMA/48/      
  1114.       L = 1            
  1115.       IF (X .GE. 0.0D0) S(L) = PLUS       
  1116.       IF (X .LT. 0.0D0) S(L) = MINUS      
  1117.       S(L+1) = ZERO    
  1118.       S(L+2) = DOT     
  1119.       X = DABS(X)      
  1120.       IF (X .NE. 0.0D0) K = DLOG(X)/DLOG(B)                  
  1121.       IF (X .EQ. 0.0D0) K = 0             
  1122.       IF (X .GT. 1.0D0) K = K + 1         
  1123.       X = X/B**K       
  1124.       IF (B*X .GE. B) K = K + 1           
  1125.       IF (B*X .GE. B) X = X/B             
  1126.       IF (EPS .NE. 0.0D0) M = -DLOG(EPS)/DLOG(B) + 4         
  1127.       IF (EPS .EQ. 0.0D0) M = 54          
  1128.       DO 10 L = 4, M   
  1129.       X = B*X          
  1130.       J = IDINT(X)     
  1131.       S(L) = DFLOAT(J)                    
  1132.       X = X - S(L)     
  1133.    10 CONTINUE         
  1134.       S(M+1) = COMMA   
  1135.       IF (K .GE. 0) S(M+2) = PLUS         
  1136.       IF (K .LT. 0) S(M+2) = MINUS        
  1137.       T = DABS(DFLOAT(K))                 
  1138.       N = M + 3        
  1139.       IF (T .GE. B) N = N + IDINT(DLOG(T)/DLOG(B))           
  1140.       L = N            
  1141.    20 J = IDINT(DMOD(T,B))                
  1142.       S(L) = DFLOAT(J)                    
  1143.       L = L - 1        
  1144.       T = T/B          
  1145.       IF (L .GE. M+3) GO TO 20            
  1146.       RETURN           
  1147.       END              
  1148.       DOUBLE PRECISION FUNCTION URAND(IY)                    
  1149.       INTEGER IY       
  1150. C                      
  1151. C      URAND IS A UNIFORM RANDOM NUMBER GENERATOR BASED  ON  THEORY  AND        
  1152. C  SUGGESTIONS  GIVEN  IN  D.E. KNUTH (1969),  VOL  2.   THE INTEGER  IY        
  1153. C  SHOULD BE INITIALIZED TO AN ARBITRARY INTEGER PRIOR TO THE FIRST CALL        
  1154. C  TO URAND.  THE CALLING PROGRAM SHOULD  NOT  ALTER  THE  VALUE  OF  IY        
  1155. C  BETWEEN  SUBSEQUENT CALLS TO URAND.  VALUES OF URAND WILL BE RETURNED        
  1156. C  IN THE INTERVAL (0,1).                 
  1157. C                      
  1158.       INTEGER IA,IC,ITWO,M2,M,MIC         
  1159.       DOUBLE PRECISION HALFM,S            
  1160.       DOUBLE PRECISION DATAN,DSQRT        
  1161.       DATA M2/0/,ITWO/2/                  
  1162.       IF (M2 .NE. 0) GO TO 20             
  1163. C                      
  1164. C  IF FIRST ENTRY, COMPUTE MACHINE INTEGER WORD LENGTH       
  1165. C                      
  1166.       M = 1            
  1167.    10 M2 = M           
  1168.       M = ITWO*M2      
  1169.       IF (M .GT. M2) GO TO 10             
  1170.       HALFM = M2       
  1171. C                      
  1172. C  COMPUTE MULTIPLIER AND INCREMENT FOR LINEAR CONGRUENTIAL METHOD              
  1173. C                      
  1174.       IA = 8*IDINT(HALFM*DATAN(1.D0)/8.D0) + 5               
  1175.       IC = 2*IDINT(HALFM*(0.5D0-DSQRT(3.D0)/6.D0)) + 1       
  1176.       MIC = (M2 - IC) + M2                
  1177. C                      
  1178. C  S IS THE SCALE FACTOR FOR CONVERTING TO FLOATING POINT    
  1179. C                      
  1180.       S = 0.5D0/HALFM                     
  1181. C                      
  1182. C  COMPUTE NEXT RANDOM NUMBER             
  1183. C                      
  1184.    20 IY = IY*IA       
  1185. C                      
  1186. C  THE FOLLOWING STATEMENT IS FOR COMPUTERS WHICH DO NOT ALLOW                  
  1187. C  INTEGER OVERFLOW ON ADDITION           
  1188. C                      
  1189.       IF (IY .GT. MIC) IY = (IY - M2) - M2                   
  1190. C                      
  1191.       IY = IY + IC     
  1192. C                      
  1193. C  THE FOLLOWING STATEMENT IS FOR COMPUTERS WHERE THE        
  1194. C  WORD LENGTH FOR ADDITION IS GREATER THAN FOR MULTIPLICATION                  
  1195. C                      
  1196.       IF (IY/2 .GT. M2) IY = (IY - M2) - M2                  
  1197. C                      
  1198. C  THE FOLLOWING STATEMENT IS FOR COMPUTERS WHERE INTEGER    
  1199. C  OVERFLOW AFFECTS THE SIGN BIT          
  1200. C                      
  1201.       IF (IY .LT. 0) IY = (IY + M2) + M2  
  1202.       URAND = DFLOAT(IY)*S                
  1203.       RETURN           
  1204.       END              
  1205.       SUBROUTINE WMUL(AR,AI,BR,BI,CR,CI)  
  1206.       DOUBLE PRECISION AR,AI,BR,BI,CR,CI,T,FLOP              
  1207. C     C = A*B          
  1208.       T = AR*BI + AI*BR                   
  1209.       IF (T .NE. 0.0D0) T = FLOP(T)       
  1210.       CR = FLOP(AR*BR - AI*BI)            
  1211.       CI = T           
  1212.       RETURN           
  1213.       END              
  1214.       SUBROUTINE WDIV(AR,AI,BR,BI,CR,CI)  
  1215.       DOUBLE PRECISION AR,AI,BR,BI,CR,CI  
  1216. C     C = A/B          
  1217.       DOUBLE PRECISION S,D,ARS,AIS,BRS,BIS,FLOP              
  1218.       S = DABS(BR) + DABS(BI)             
  1219.       IF (S .EQ. 0.0D0) CALL ERROR(27)    
  1220.       IF (S .EQ. 0.0D0) RETURN            
  1221.       ARS = AR/S       
  1222.       AIS = AI/S       
  1223.       BRS = BR/S       
  1224.       BIS = BI/S       
  1225.       D = BRS**2 + BIS**2                 
  1226. SHAR_EOF
  1227. #    End of shell archive
  1228. exit 0
  1229. -- 
  1230. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1231. Have five nice days.
  1232.